// calc.js - 命令行计算器

/**
 * 打印程序使用说明
 */
function printUsage() {
    console.log(`
数学表达式计算器

用法:
  node calc.js <expression>
  node calc.js --help
  node calc.js -h

示例:
  node calc.js "2 + 3"
  node calc.js "10 * 5"
  node calc.js "15 / 3"
  node calc.js "2 ** 8"
  node calc.js "(1 + 2) * 3"

选项:
  --help, -h    显示此帮助信息

注意:
  - 数学表达式需要用引号包围
  - 支持 +, -, *, /, %, ** 运算符
  - 支持括号 ()
  - 多余的参数将被忽略
    `);
}

/**
 * 检查表达式是否只包含合法的数学字符
 * 防止代码注入攻击
 */
function isValidMathExpression(expr) {
    // 正则表达式：只允许数字、基本运算符、括号和小数点
    const mathRegex = /^[\d\s+\-*/%().]+$/;
    
    // 检查是否包含字母（防止变量名如a+b）
    const containsLetters = /[a-zA-Z]/.test(expr);
    
    return mathRegex.test(expr) && !containsLetters;
}

/**
 * 安全地计算数学表达式
 * 使用Function构造函数但有严格验证
 */
function safeEvaluate(expression) {
    // 预处理：移除多余的空格
    const cleanedExpr = expression.trim().replace(/\s+/g, ' ');
    
    // 验证表达式合法性
    if (!isValidMathExpression(cleanedExpr)) {
        throw new Error('表达式包含非法字符或变量名');
    }
    
    try {
        // 使用Function构造函数进行求值（比eval稍安全）
        // eslint-disable-next-line no-new-func
        const result = new Function(`return ${cleanedExpr};`)();
        
        // 检查结果是否为有效数字
        if (typeof result !== 'number' || isNaN(result) || !isFinite(result)) {
            throw new Error('计算结果无效');
        }
        
        return Number(result.toFixed(10)); // 保留10位小数，避免浮点精度问题
    } catch (error) {
        throw new Error('表达式语法错误或计算失败');
    }
}

/**
 * 主程序逻辑
 */
function main() {
    // 获取命令行参数
    // process.argv[0] = node路径
    // process.argv[1] = 脚本路径
    // process.argv[2...] = 用户参数
    const args = process.argv.slice(2);
    
    // 检查参数数量
    if (args.length === 0) {
        console.log('❌ 错误：未提供数学表达式\n');
        printUsage();
        process.exit(1);
    }
    
    // 检查是否请求帮助
    const firstArg = args[0].toLowerCase();
    if (firstArg === '--help' || firstArg === '-h') {
        printUsage();
        process.exit(0);
    }
    
    // 获取表达式（只取第一个参数，多余的忽略）
    const expression = args[0];
    
    // 验证并计算表达式
    try {
        const result = safeEvaluate(expression);
        console.log(`✅ 计算结果: ${expression} = ${result}`);
    } catch (error) {
        console.log(`❌ 错误：${error.message}`);
        console.log(`   表达式: "${expression}"`);
        console.log('\n提示：请确保表达式只包含数字和合法的数学运算符');
        process.exit(1);
    }
}

// 程序入口
main();